{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:06:57.110541Z",
     "start_time": "2020-04-21T10:06:57.103540Z"
    }
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 下载数据集"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可使用迅雷等下载工具手动下载数据集，下载后地址在/root/.keras/dataset，对应windows应该在C盘用户文件夹中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:06:57.563179Z",
     "start_time": "2020-04-21T10:06:57.117437Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "mnist = tf.keras.datasets.mnist\n",
    "\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "# 归一化\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## NN（多层感知机）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 建立模型\n",
    "\n",
    "Sequential方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:06:57.649478Z",
     "start_time": "2020-04-21T10:06:57.564921Z"
    }
   },
   "outputs": [],
   "source": [
    "model = tf.keras.models.Sequential([\n",
    "  tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
    "  tf.keras.layers.Dense(128, activation='relu'),\n",
    "  tf.keras.layers.Dropout(0.2),\n",
    "  tf.keras.layers.Dense(10, activation='softmax')\n",
    "])\n",
    "\n",
    "model.compile(optimizer='adam',\n",
    "              loss='sparse_categorical_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练、验证模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:17.176623Z",
     "start_time": "2020-04-21T10:06:57.650946Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples\n",
      "Epoch 1/5\n",
      "60000/60000 [==============================] - 4s 62us/sample - loss: 0.2963 - acc: 0.9130\n",
      "Epoch 2/5\n",
      "60000/60000 [==============================] - 4s 63us/sample - loss: 0.1399 - acc: 0.9586\n",
      "Epoch 3/5\n",
      "60000/60000 [==============================] - 4s 63us/sample - loss: 0.1055 - acc: 0.9685\n",
      "Epoch 4/5\n",
      "60000/60000 [==============================] - 4s 58us/sample - loss: 0.0873 - acc: 0.9732\n",
      "Epoch 5/5\n",
      "60000/60000 [==============================] - 4s 64us/sample - loss: 0.0758 - acc: 0.9767\n",
      "10000/10000 - 1s - loss: 0.0798 - acc: 0.9759\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.07980715533220209, 0.9759]"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(x_train, y_train, epochs=5)\n",
    "\n",
    "model.evaluate(x_test,  y_test, verbose=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**使用简单NN网络训练后，训练集与验证集准确度都达到97.6%**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN（卷积神经网络）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 导包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:17.188062Z",
     "start_time": "2020-04-21T10:07:17.180269Z"
    }
   },
   "outputs": [],
   "source": [
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.models import Sequential, Model\n",
    "from tensorflow.keras.layers import Input, Dense, Dropout, Flatten\n",
    "from tensorflow.keras.layers import Conv2D, MaxPooling2D\n",
    "from tensorflow.keras import backend as K"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:17.289581Z",
     "start_time": "2020-04-21T10:07:17.191476Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(60000, 28, 28, 1) (10000, 28, 28, 1)\n"
     ]
    }
   ],
   "source": [
    "# 清除之前的模型\n",
    "tf.keras.backend.clear_session()\n",
    "\n",
    "# 将训练数据变形为适合输入网络的形状\n",
    "img_rows, img_cols = 28, 28\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "print(x_train.shape, x_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 建立模型\n",
    "\n",
    "函数方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:17.573121Z",
     "start_time": "2020-04-21T10:07:17.297095Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"model\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 28, 28, 1)]       0         \n",
      "_________________________________________________________________\n",
      "conv2d (Conv2D)              (None, 26, 26, 32)        320       \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 24, 24, 64)        18496     \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 12, 12, 64)        0         \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 12, 12, 64)        0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 9216)              0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 128)               1179776   \n",
      "_________________________________________________________________\n",
      "dropout_1 (Dropout)          (None, 128)               0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 10)                1290      \n",
      "=================================================================\n",
      "Total params: 1,199,882\n",
      "Trainable params: 1,199,882\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "inputs = Input(shape=(28, 28, 1))\n",
    "x = Conv2D(32, kernel_size=(3, 3), activation='relu')(inputs)\n",
    "x = Conv2D(64, kernel_size=(3, 3), activation='relu')(x)\n",
    "x = MaxPooling2D(pool_size=(2, 2))(x)\n",
    "x = Dropout(0.25)(x)\n",
    "x = Flatten()(x)\n",
    "x = Dense(128, activation='relu')(x)\n",
    "x = Dropout(0.5)(x)\n",
    "predictions = Dense(10, activation='softmax')(x)\n",
    "\n",
    "model = Model(inputs=inputs, outputs=predictions)\n",
    "model.compile(loss='sparse_categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:55.075890Z",
     "start_time": "2020-04-21T10:07:17.574496Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/12\n",
      "60000/60000 [==============================] - 4s 59us/sample - loss: 0.2514 - acc: 0.9238 - val_loss: 0.0537 - val_acc: 0.9835\n",
      "Epoch 2/12\n",
      "60000/60000 [==============================] - 3s 46us/sample - loss: 0.0868 - acc: 0.9739 - val_loss: 0.0417 - val_acc: 0.9875\n",
      "Epoch 3/12\n",
      "60000/60000 [==============================] - 3s 51us/sample - loss: 0.0656 - acc: 0.9800 - val_loss: 0.0305 - val_acc: 0.9893\n",
      "Epoch 4/12\n",
      "60000/60000 [==============================] - 3s 52us/sample - loss: 0.0533 - acc: 0.9837 - val_loss: 0.0267 - val_acc: 0.9910\n",
      "Epoch 5/12\n",
      "60000/60000 [==============================] - 3s 51us/sample - loss: 0.0448 - acc: 0.9862 - val_loss: 0.0281 - val_acc: 0.9908\n",
      "Epoch 6/12\n",
      "60000/60000 [==============================] - 3s 51us/sample - loss: 0.0397 - acc: 0.9872 - val_loss: 0.0316 - val_acc: 0.9902\n",
      "Epoch 7/12\n",
      "60000/60000 [==============================] - 3s 49us/sample - loss: 0.0346 - acc: 0.9893 - val_loss: 0.0289 - val_acc: 0.9905\n",
      "Epoch 8/12\n",
      "60000/60000 [==============================] - 3s 53us/sample - loss: 0.0298 - acc: 0.9906 - val_loss: 0.0299 - val_acc: 0.9916\n",
      "Epoch 9/12\n",
      "60000/60000 [==============================] - 3s 49us/sample - loss: 0.0279 - acc: 0.9908 - val_loss: 0.0252 - val_acc: 0.9926\n",
      "Epoch 10/12\n",
      "60000/60000 [==============================] - 3s 51us/sample - loss: 0.0245 - acc: 0.9916 - val_loss: 0.0248 - val_acc: 0.9924\n",
      "Epoch 11/12\n",
      "60000/60000 [==============================] - 3s 52us/sample - loss: 0.0237 - acc: 0.9924 - val_loss: 0.0316 - val_acc: 0.9908\n",
      "Epoch 12/12\n",
      "60000/60000 [==============================] - 3s 48us/sample - loss: 0.0207 - acc: 0.9931 - val_loss: 0.0265 - val_acc: 0.9918\n",
      "Test loss: 0.026530563170787547\n",
      "Test accuracy: 0.9918\n"
     ]
    }
   ],
   "source": [
    "batch_size = 128\n",
    "epochs = 12\n",
    "\n",
    "model.fit(x_train, y_train,\n",
    "          batch_size=batch_size,\n",
    "          epochs=epochs,\n",
    "          verbose=1,\n",
    "          validation_data=(x_test, y_test))\n",
    "score = model.evaluate(x_test, y_test, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**使用CNN网络训练后，训练集与验证集准确度都达到99.2%**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN+数据增强\n",
    "\n",
    "参考：[Keras官方文档](https://keras.io/zh/preprocessing/image/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:55.306501Z",
     "start_time": "2020-04-21T10:07:55.077037Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(60000, 28, 28, 1) (10000, 28, 28, 1)\n"
     ]
    }
   ],
   "source": [
    "# 清除之前的模型\n",
    "tf.keras.backend.clear_session()\n",
    "\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "# 将训练数据变形为适合输入网络的形状\n",
    "img_rows, img_cols = 28, 28\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "print(x_train.shape, x_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 原始图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:55.944712Z",
     "start_time": "2020-04-21T10:07:55.307613Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "for i in range(9):\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(x_train[i].reshape(28,28), cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据增强演示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 旋转（0~30度）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:56.629705Z",
     "start_time": "2020-04-21T10:07:55.945834Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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AwYMiI4df/zxAAwePBiAddZZJ2qzRaD+/fsDYQHphhtuiPqYS62cyOIUQoiEyOKsx1577QXAkCFDomNrrbUWEL7tbMEB4IcffkhxdK2Xfv1yGzjOP//86Njmm28OwKJFiwDYe++9o7aff/4ZCFqZZaPFvMqyyio5W61Lly5AsCpPOOGEqE/fvn0Lfue5556Lni9fvrzg9/bZZx8A7r///qiPLE4hhKhCWr3F2a5dOwB23313AI455hgA1lxzzajPV199BcBHH30EFH6j/fTTT2kMs9XRuXNnAI499lgAzjrrLAB++eWXqI9Zj1275krhxK1/088sHFEdbLLJJkDQ9bjjjgOgd+/eUR+bLTz//PMAnHLKKVFbr169ADjkkEOAEDbYvn37cg57BfSuEkKIhOjGKYQQCVnpVN05dwdwCLDAe79t/lhH4H6gO/ARcLT3/qvyDbO0rLvuutFzczKfffbZQHBMf/nll1Gfe++9F4C//vWvAHz99depjLOcVLuuu+66KxCmdLZH+corr4z63H777QAceeSRAFxxxRVRm03jv/vuu4LXrYFq0dZChcztAnD11VcDYapti3ZxbEHv1FNPLXgNYXeYhf9ZiOBGG20U9TH327Jly0rwXzRMMRbnKODAesdGABO8972ACfnXIluMQrrWKqOQtmVlpRan9/6FfKH3OIcBe+efjwaeAy4s4bjKyrbbbhs9/93vfgfATjvtBATL5Omnn4763HbbbUA6YQ5pUY26du8ehnP00UcDIbjdrP5///vfUR/Tw6yWNm3aRG22KPTBBx8AwfpJO4tOJagWbe1a77bbbtGx/fbbDwiameU4e/bsqI9ZpZ9+umI5pA4dOgDBCrXFIQtNgxA+WE6Ls7mr6p2993UA3vs659yGjXVUudFMIV1rl6K0la7FUfZwJO/9SGAkVC4V/6qr5v7Njh07AnDEEaFS8cCBA4EQ5vLKK68AcNddd0V90s68kgVKqatZg7ZNEsL2yW+++QaAO++8EwghYRA0M+vFwlgAPvzwQwDq6upsvC0ZYquhHJ/X+AxvyZIlQLAYLeToqaeeivq8+OKLQMMWo/kv629xjlucFopmYYTloLmr6p8757oA5B8XlG5IooJI19pF2paQ5lqc44ATgavyj4+UbERlwIJuL7roIiCswkLI/ffSSy8BwZ/56quvpjnEaqEiupo/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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "datagen = ImageDataGenerator(rotation_range=30)\n",
    "datagen.fit(x_train)\n",
    "gen_data = datagen.flow(x_train[:9],batch_size=1,shuffle=False)\n",
    "for i,img in enumerate(gen_data):\n",
    "    if i+1 == 10:\n",
    "        break\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(img[0,...,0], cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### PCA降维（zca白化）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:57.447275Z",
     "start_time": "2020-04-21T10:07:56.630848Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/root/anaconda3/lib/python3.7/site-packages/keras_preprocessing/image/image_data_generator.py:336: UserWarning: This ImageDataGenerator specifies `zca_whitening`, which overrides setting of `featurewise_center`.\n",
      "  warnings.warn('This ImageDataGenerator specifies '\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "datagen = ImageDataGenerator(zca_whitening=True)\n",
    "datagen.fit(x_train)\n",
    "gen_data = datagen.flow(x_train[:9],batch_size=1,shuffle=False)\n",
    "for i,img in enumerate(gen_data):\n",
    "    if i+1 == 10:\n",
    "        break\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(img[0,...,0], cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 平移"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:58.136654Z",
     "start_time": "2020-04-21T10:07:57.448488Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "datagen = ImageDataGenerator(width_shift_range=0.3,height_shift_range=0.3)\n",
    "datagen.fit(x_train)\n",
    "gen_data = datagen.flow(x_train[:9],batch_size=1,shuffle=False)\n",
    "for i,img in enumerate(gen_data):\n",
    "    if i+1 == 10:\n",
    "        break\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(img[0,...,0], cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 缩放"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:59.025038Z",
     "start_time": "2020-04-21T10:07:58.137704Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "datagen = ImageDataGenerator(zoom_range=0.5)\n",
    "datagen.fit(x_train)\n",
    "gen_data = datagen.flow(x_train[:9],batch_size=1,shuffle=False)\n",
    "for i,img in enumerate(gen_data):\n",
    "    if i+1 == 10:\n",
    "        break\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(img[0,...,0], cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 随机翻转"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:59.711428Z",
     "start_time": "2020-04-21T10:07:59.026187Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "datagen = ImageDataGenerator(horizontal_flip=True)\n",
    "datagen.fit(x_train)\n",
    "gen_data = datagen.flow(x_train[:9],batch_size=1,shuffle=False)\n",
    "for i,img in enumerate(gen_data):\n",
    "    if i+1 == 10:\n",
    "        break\n",
    "    plt.subplot(3,3,i+1)\n",
    "    plt.imshow(img[0,...,0], cmap=\"gray\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据增强应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:07:59.826557Z",
     "start_time": "2020-04-21T10:07:59.712549Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"model\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 28, 28, 1)]       0         \n",
      "_________________________________________________________________\n",
      "conv2d (Conv2D)              (None, 26, 26, 32)        320       \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 24, 24, 64)        18496     \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 12, 12, 64)        0         \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 12, 12, 64)        0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 9216)              0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 128)               1179776   \n",
      "_________________________________________________________________\n",
      "dropout_1 (Dropout)          (None, 128)               0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 10)                1290      \n",
      "=================================================================\n",
      "Total params: 1,199,882\n",
      "Trainable params: 1,199,882\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "inputs = Input(shape=(28, 28, 1))\n",
    "x = Conv2D(32, kernel_size=(3, 3), activation='relu')(inputs)\n",
    "x = Conv2D(64, kernel_size=(3, 3), activation='relu')(x)\n",
    "x = MaxPooling2D(pool_size=(2, 2))(x)\n",
    "x = Dropout(0.25)(x)\n",
    "x = Flatten()(x)\n",
    "x = Dense(128, activation='relu')(x)\n",
    "x = Dropout(0.5)(x)\n",
    "predictions = Dense(10, activation='softmax')(x)\n",
    "\n",
    "model = Model(inputs=inputs, outputs=predictions)\n",
    "model.compile(loss='sparse_categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用多线程处理数据增强，但ImageDataGenerator类进程不安全，多进程处理时需要手动实现数据生成类，并继承于Sequence类 [参考](https://github.com/matterport/Mask_RCNN/issues/514)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-21T10:09:12.770324Z",
     "start_time": "2020-04-21T10:07:59.827617Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.3136 - acc: 0.9145\n",
      "469/468 - 4s - loss: 1.6954 - acc: 0.4479 - val_loss: 0.2667 - val_acc: 0.9145\n",
      "Epoch 2/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.2903 - acc: 0.9318\n",
      "469/468 - 4s - loss: 0.6020 - acc: 0.8062 - val_loss: 0.2355 - val_acc: 0.9318\n",
      "Epoch 3/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1485 - acc: 0.9642\n",
      "469/468 - 4s - loss: 0.4173 - acc: 0.8702 - val_loss: 0.1259 - val_acc: 0.9642\n",
      "Epoch 1/20\n",
      "Epoch 4/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1823 - acc: 0.9753\n",
      "469/468 - 4s - loss: 0.3280 - acc: 0.9005 - val_loss: 0.1017 - val_acc: 0.9753\n",
      "Epoch 5/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1296 - acc: 0.9752\n",
      "469/468 - 4s - loss: 0.2892 - acc: 0.9119 - val_loss: 0.0825 - val_acc: 0.9752\n",
      "Epoch 6/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1007 - acc: 0.9781\n",
      "469/468 - 4s - loss: 0.2629 - acc: 0.9213 - val_loss: 0.0676 - val_acc: 0.9781\n",
      "Epoch 7/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0762 - acc: 0.9828\n",
      "469/468 - 4s - loss: 0.2375 - acc: 0.9292 - val_loss: 0.0632 - val_acc: 0.9828\n",
      "Epoch 8/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1353 - acc: 0.9675\n",
      "469/468 - 4s - loss: 0.2279 - acc: 0.9320 - val_loss: 0.0835 - val_acc: 0.9675\n",
      "Epoch 9/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1289 - acc: 0.9755\n",
      "469/468 - 4s - loss: 0.2138 - acc: 0.9366 - val_loss: 0.0778 - val_acc: 0.9755\n",
      "Epoch 10/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0842 - acc: 0.9833\n",
      "469/468 - 4s - loss: 0.2014 - acc: 0.9387 - val_loss: 0.0503 - val_acc: 0.9833\n",
      "Epoch 11/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.1033 - acc: 0.9834\n",
      "469/468 - 4s - loss: 0.1923 - acc: 0.9424 - val_loss: 0.0486 - val_acc: 0.9834\n",
      "Epoch 12/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0695 - acc: 0.9863\n",
      "469/468 - 4s - loss: 0.1900 - acc: 0.9449 - val_loss: 0.0451 - val_acc: 0.9863\n",
      "Epoch 13/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0844 - acc: 0.9743\n",
      "469/468 - 4s - loss: 0.1873 - acc: 0.9452 - val_loss: 0.0582 - val_acc: 0.9743\n",
      "Epoch 14/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0659 - acc: 0.9847\n",
      "469/468 - 4s - loss: 0.1780 - acc: 0.9476 - val_loss: 0.0402 - val_acc: 0.9847\n",
      "Epoch 15/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0765 - acc: 0.9816\n",
      "469/468 - 4s - loss: 0.1735 - acc: 0.9494 - val_loss: 0.0497 - val_acc: 0.9816\n",
      "Epoch 16/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0593 - acc: 0.9893\n",
      "469/468 - 4s - loss: 0.1725 - acc: 0.9493 - val_loss: 0.0396 - val_acc: 0.9893\n",
      "Epoch 17/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0907 - acc: 0.9831\n",
      "469/468 - 4s - loss: 0.1654 - acc: 0.9513 - val_loss: 0.0478 - val_acc: 0.9831\n",
      "Epoch 18/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0529 - acc: 0.9875\n",
      "469/468 - 4s - loss: 0.1622 - acc: 0.9525 - val_loss: 0.0435 - val_acc: 0.9875\n",
      "Epoch 19/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0712 - acc: 0.9879\n",
      "469/468 - 4s - loss: 0.1597 - acc: 0.9527 - val_loss: 0.0340 - val_acc: 0.9879\n",
      "Epoch 20/20\n",
      "WARNING:tensorflow:Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the `keras.utils.Sequence` class.\n",
      "Epoch 1/20\n",
      "10112/468 - 1s - loss: 0.0610 - acc: 0.9894\n",
      "469/468 - 4s - loss: 0.1561 - acc: 0.9541 - val_loss: 0.0311 - val_acc: 0.9894\n",
      "Test loss: 0.04075803493621643\n",
      "Test accuracy: 0.9871\n"
     ]
    }
   ],
   "source": [
    "# 数据增强后，可适当增加训练轮次\n",
    "batch_size = 128\n",
    "epochs = 20\n",
    "\n",
    "# 进行PCA降维、随机旋转、随机横向、纵向平移\n",
    "datagen = ImageDataGenerator(\n",
    "    rotation_range=20,\n",
    "    width_shift_range=0.2,\n",
    "    height_shift_range=0.2)\n",
    "\n",
    "datagen.fit(x_train)\n",
    "\n",
    "# 使用多线程处理数据增强，可能导致训练集数据被重复训练\n",
    "# use_multiprocessing为多线程开关，workers为线程数\n",
    "model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),\n",
    "                    steps_per_epoch=len(x_train) / batch_size,\n",
    "                    epochs=epochs,\n",
    "                    verbose=2,\n",
    "                    validation_data=(x_test, y_test),\n",
    "                    use_multiprocessing=True,\n",
    "                    workers=16)\n",
    "\n",
    "score = model.evaluate(x_test, y_test, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**数据增强后，测试集精度为98.7%**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
